<template>
  <div class="news-box">
    <div
      class="scroll-container"
      ref="scrollContainer"
      @scroll.passive="handleScroll"
    >
      <div :style="blankFillStyle">
        <!-- 根据待显示新闻列表数组，显示新闻列表 -->
        <div v-for="item in showDataList" :key="item.title">
          <router-link
            class="one-new"
            :to="
              '/article/' +
              item.title +
              '/' +
              item.reads +
              '/' +
              item.from +
              '/' +
              item.date +
              '/' +
              item.image
            "
          >
            <!-- 新闻左侧标题、评论、来源部分 -->
            <div class="new-left">
              <h3>{{ item.title }}</h3>
              <div>
                <p>
                  <img src="../assets/icons/msg.png" alt="评" />
                  <span>{{ item.reads }}</span>
                  <span>{{ item.from }}</span>
                </p>
                <h4>{{ item.date }}</h4>
              </div>
            </div>
            <!-- 新闻右侧图片部分 -->
            <div class="new-right">
              <img :src="imgsList[item.image]" alt="PIC" />
            </div>
          </router-link>
        </div>
        <!-- 请求状态下 显示对应 msg 提示信息 -->
        <div v-if="isShowMsg" class="msg">
          <h2>{{ msg }}</h2>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
// 引入准备好的新闻图片相关信息
import imgsList from "../components/newsImgs.js";
export default {
  name: "index",
  data() {
    return {
      // 用来保存 所有列表元素
      allDataList: [],
      // 数据请求状态判断
      isRequestStatus: true,
      //是否显示提示信息
      isShowMsg: true,
      // 提示显示信息
      msg: "小二正在努力，请耐心等待...",
      // 图片数组
      imgsList,
      //单条新闻的高度,根据页面样式计算出来即可
      onHeight: 100,
      //容器的最大容积
      containerMaxSize: 0,
      //滚动容器 可视区 第一个元素的索引
      startIndex: 0,

      //是否设置了请求帧标识
      isSetRequestAnimationFrame: false,

      //处理兼容性问题
      requestAnimationFrame:
        window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.msRequestAnimationFrame,

      //滚动距离
      currentScrollTop: 0,
    };
  },
  async created() {
    //请求新闻列表数据
    let newsList = await this.getNewsList(10);
    if (!newsList) return;
    this.allDataList = newsList;
  },
  mounted() {
    this.getContainerMaxSize();

    //浏览器窗口大小或者设备纵横向 变化时，重新计算 容器的最大容积
    window.onresize = this.getContainerMaxSize;
    window.onorientationchange = this.getContainerMaxSize;
  },
  activated() {
    this.$nextTick(() => {
      console.log(this.currentScrollTop);
      //滚动到之间的位置
      this.$refs.scrollContainer.scrollTop = this.currentScrollTop;
    });
  },
  computed: {
    //滚动容器 可视区 最后一个元素的索引
    endIndex() {
      let endIndex = this.startIndex + this.containerMaxSize * 2;
      if (!this.allDataList[endIndex - 1]) {
        endIndex = this.allDataList.length;
      }
      return endIndex;
    },
    //定义一个 待显示的元素列表数组
    showDataList() {
      return this.allDataList.slice(this.getStartIndex(), this.endIndex);
    },
    //计算上下空白的填充高度
    blankFillStyle() {
      return {
        paddingTop: this.getStartIndex() * this.onHeight + "px",
        paddingBottom:
          this.onHeight * (this.allDataList.length - this.endIndex) + "px",
      };
    },
  },
  methods: {
    // 发送请求获取新的请求模拟数据，这个是跨域请求的网络mock数据
    getNewsList(num) {
      this.isRequestStatus = true;
      this.isShowMsg = true;
      this.msg = "小二正在努力，请耐心等待...";

      return (
        this.$axios
          //不要用localhost，否则移动端无法访问。
          //192.168.43.168是电脑局域网ipv4地址,查看方式：cmd命令 > ipconfig
          .get("http://192.168.43.168:4000/data?num=" + num)
          .then((res) => {
            this.isRequestStatus = false;
            return res.data.list;
          })
          .catch(() => {
            this.msg = "亲，网络请求出错啦！赶快检查吧...";
            return false;
          })
      );
    },

    //计算容器的最大容积
    getContainerMaxSize() {
      this.containerMaxSize =
        ~~(this.$refs.scrollContainer.offsetHeight / this.onHeight) + 2;
    },

    //滚动事件
    handleScroll() {
      //滚动事件 节流优化 之 请求动画帧
      if (!this.isSetRequestAnimationFrame) {
        this.isSetRequestAnimationFrame = true;

        requestAnimationFrame(() => {
          this.updateData();
          this.isSetRequestAnimationFrame = false;
        });
      }

      //保存当前滚动距离
      this.currentScrollTop = this.$refs.scrollContainer.scrollTop;
    },

    //滚动事件 真正要执行的任务
    async updateData() {
      //垂直向上滚动的距离
      this.startIndex = ~~(
        this.$refs.scrollContainer.scrollTop / this.onHeight
      );

      //判断下拉是否触底
      if (
        this.startIndex + this.containerMaxSize > this.allDataList.length - 1 &&
        !this.isRequestStatus
      ) {
        //重新请求10条数据
        let newlist = await this.getNewsList(10);
        if (!newlist) return;
        //this.allDataList = [...this.allDataList, ...newlist];
        this.allDataList.push(...newlist);
        this.isShowMsg = false;
      }
    },

    //计算 截取数据的缓冲区的 开始索引
    getStartIndex() {
      let startIndex = 0;
      if (this.startIndex < this.containerMaxSize) {
        startIndex = 0;
      } else {
        startIndex = this.startIndex - this.containerMaxSize;
      }
      return startIndex;
    },
  },
};
</script>

<style lang="scss" scoped>
.news-box {
  width: 100%;
  max-width: 800px;
  height: 100%;
  .scroll-container {
    width: 100%;
    height: 100%;
    overflow-y: auto; //非常重要
    .one-new {
      text-decoration: none;
      display: block;
      display: flex;
      flex-direction: row;
      flex-wrap: nowrap;
      justify-content: space-between;
      border-bottom: 1px solid #ddd;
      padding: 14px 10px 5px;
      .new-left {
        height: 80px;
        position: relative;
        h3 {
          padding: 0;
          margin: 0;
          font-size: 16px;
          text-align: justify;
          color: #555;
        }
        div {
          position: absolute;
          width: 100%;
          bottom: 10px;
          display: flex;
          flex-direction: row;
          flex-wrap: nowrap;
          justify-content: space-between;
          align-items: center;
          p {
            display: flex;
            flex-direction: row;
            flex-wrap: nowrap;
            justify-content: space-between;
            align-items: center;
            img {
              height: 16px;
            }
            span {
              font-size: 12px;
              color: #555;
              margin-left: 3px;
              margin-right: 3px;
            }
          }
          h4 {
            font-size: 12px;
            color: #888;
          }
        }
      }
      .new-right {
        margin-left: 10px;
        img {
          height: 68px;
        }
      }
    }
    .msg h2 {
      font-size: 18px;
      text-align: center;
      color: #666;
      padding: 58px 0;
    }
  }
}
</style>
